/**
 * 
 */
package org.ztest.http;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * @author Administrator
 *
 */
final public class HttpUtil
{
	private HttpUtil() {}
	
	private static final int HTTP_TIMEOUT_MS = 1000 * 20; // 连接或者读取超时

	/**
	 * 发送HTTP GET请求
	 * 
	 * @param getUrl 请求url，附带get参数
	 * @return 应答消息
	 * @throws Exception
	 */
	public static String GET(String getUrl) throws Exception
	{
		Objects.requireNonNull(getUrl, "GET: getUrl 不能为空");

		URL url = new URL(getUrl);
		URLConnection conn = url.openConnection();
		conn.setConnectTimeout(HTTP_TIMEOUT_MS);
		conn.setReadTimeout(HTTP_TIMEOUT_MS);
		conn.connect();
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())))
		{
			String line;
			StringBuilder builder = new StringBuilder();
			while ((line = reader.readLine()) != null)
			{
				builder.append(line);
			}
			return builder.toString();
		}
	}
	
	/**
	 * 发送HTTP GET请求,并针对返回的每一行内容执行consumer指定的操作
	 * @param getUrl 请求url
	 * @param consumer 
	 * @throws Exception
	 */
	public static void GET(String getUrl, Consumer<String> consumer) throws Exception
	{
		Objects.requireNonNull(getUrl, "GET: getUrl 不能为空");
		Objects.requireNonNull(getUrl, "GET: consumer 不能为空");

		URL url = new URL(getUrl);
		URLConnection conn = url.openConnection();
		conn.setConnectTimeout(HTTP_TIMEOUT_MS);
		conn.setReadTimeout(HTTP_TIMEOUT_MS);
		conn.connect();
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())))
		{
			String line;
			while ((line = reader.readLine()) != null)
			{
				consumer.accept(line);
			}
		}
	}
	
	/**
	 * 发送HTTP GET请求
	 * @param getUrl 请求url
	 * @return 返回的byte数组
	 * @throws IOException
	 */
	public static byte[] GET1(String getUrl) throws IOException, NullPointerException
	{
		Objects.requireNonNull(getUrl, "GET: getUrl 不能为空");
		
		URL url = new URL(getUrl);
		URLConnection conn = url.openConnection();
		conn.setConnectTimeout(HTTP_TIMEOUT_MS);
		conn.setReadTimeout(HTTP_TIMEOUT_MS);
		conn.connect();
		try (InputStream in = conn.getInputStream())
		{
			System.err.println("downloading " + getUrl + ", size " + conn.getContentLength());
			byte[] buffer = new byte[conn.getContentLength()];
			int rdx = 0, totalSize = 0;
			while ((rdx = in.read(buffer, totalSize, buffer.length - totalSize)) >= 0 && totalSize < buffer.length)
			{
				totalSize += rdx;
			}
			return buffer;
		}
	}
	
	/**
	 * 发送HTTP POST请求，数据将被编码为键值对
	 * 
	 * @param postUrl 请求url
	 * @param param post数据
	 * @return 应答
	 * @throws Exception
	 */
	public static byte[] POST(String postUrl, byte[] param) throws Exception
	{
		Objects.requireNonNull(postUrl, "POST: postUrl 不能为空");
		Objects.requireNonNull(param, "POST: param 不能为空");

		URL url = new URL(postUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setDoOutput(true);
		conn.setConnectTimeout(HTTP_TIMEOUT_MS);
		conn.setReadTimeout(HTTP_TIMEOUT_MS);
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		conn.setRequestProperty("Content-Length", String.valueOf(param.length));
		try (OutputStream out = conn.getOutputStream())
		{
			out.write(param);
			out.flush();
		}
		try (BufferedInputStream in = new BufferedInputStream(conn.getInputStream()))
		{
			byte[] receiveBytes = new byte[in.available()];
			in.read(receiveBytes);
			return receiveBytes;
		}
	}
}
